package magnetic.field.arduino;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.util.Enumeration;


public class SensorHall implements SerialPortEventListener {
       
SerialPort serialPort;


        private static final String PORT_NAMES[] = { "COM5" }; // Porta Usada
        // private static final String PORT_NAMES[] = { "/dev/tty.usbmodem411" }; //
       

        private static BufferedReader input;
        private static OutputStream output;
        private static final int TIME_OUT = 2000; // Milissegundos para bloqueio
                                                                                                // enquanto aguarda a porta
                                                                                                // abrir

        private static final int DATA_RATE = 9600; // baud rate da porta

        public void initialize() {
        	CommPortIdentifier portId = null;
            @SuppressWarnings("rawtypes")
			Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

                while (portEnum.hasMoreElements()) {
                        CommPortIdentifier currPortId = (CommPortIdentifier) portEnum
                                        .nextElement();
                        for (String portName : PORT_NAMES) {
                                if (currPortId.getName().equals(portName)) {
                                        portId = currPortId;
                                        break;
                                }
                        }
                }
                if (portId == null) {
                        System.out.println("\nPorta COM nao encontrada\n");
                        return;
                }

                try {
                        serialPort = (SerialPort) portId.open(this.getClass().getName(),
                                        TIME_OUT);

                        serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8,
                                        SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

                        input = new BufferedReader(new InputStreamReader(
                                        serialPort.getInputStream(),"ISO-8859-1"));         // Mudança de codificação padrão UTF-8 ( -127 a 127) para
                        serialPort.addEventListener((SerialPortEventListener) this);// ISO-8859-1 (0 a 255), pois o xbee envia de 0 a 255,
                                                                                                                                                
                        serialPort.notifyOnDataAvailable(true);
                } catch (Exception e) {
                        System.err.println(e.toString());
                }
        }

        /**
         * Deve ser chamado quando voc� parar de usar a porta. Evita travamento de
         * porta em plataformas Linux.
         */
        public synchronized void close() {
                if (serialPort != null) {
                        serialPort.removeEventListener();
                        serialPort.close();
                }
        }

        public synchronized void serialEvent(SerialPortEvent oEvent) {
               
                if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                       
                       
                        try {
                        	 
                               int dado = Integer.parseInt(input.readLine());
                        	   System.out.println(dado);
                               

                        } catch (Exception e) {
                                System.err.println(e.toString());

                        }
                }

        }
       
        /* Método para enviar um dado ao arduino, UM DADO, digo isso porque caso você queira mandar
         * mais de um, você terá que alterar o número desta sequÊncia que indica quantos bits são enviados.
         * Alterando este número vc altera a posição do checksum e resumindo, nada é enviado. Eu sei,
         * este código não está nada genérico :(
         *
         * Pelo menos o calculo do valor do checksum é genérico, a fórmula tem no livro do Faludi sobre Xbee
         * e tem também na net, só dá uma procurada.
         *
         *
         * */
       
       
        public void enviar(int a) {
               
                try {
                       
                        output = serialPort.getOutputStream();
                       
                        int soma = 0;
                        int checksum = 0;
                        int dat[]={0x7E,0x00,15,0x10,0x00,0x00,0x13,0xA2,0x00,0x40,0xA9,0xC4,0xFC,0xFF,0xFE,0,0,a,113};
                       
                        for (int i = 3; i < ((dat.length) - 1); i++) {
                                soma = soma + dat[i];
                        }
                       
                        soma = soma % 256;
                        checksum = 0xFF - soma;
                        dat[18] = checksum;
                       
                        for (int i = 0; i <dat.length; i++) {
                                output.write(dat[i]);  
                        }
       
               
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
               
               
        }
       
        public static void main(String[] args) {
               
                SensorHall app = new SensorHall();
                app.initialize();

        }
}
